﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Motion.MotionPlatform.Tools;
using System.IO;
using System.Data;
/*
 *  工程完成后，要遍历所有运动表格自动生成一个参数关联表格，记录所有随机变量和输入变量所影响到的行。
 *  
 *  0、设计一个存储结构来存储随机变量和输入变量,使用这些变量的行，以及他们所影响到的物体信息（不断扩展），这些变量直接（通过变量）间接（变量影响的物体）影响到的行。
 *	1、遍历所有运动表格，遍历表格有两种路径：1、按照教的路径；2、按照练，考的时候遍历；
 *	2、在每一行中对每种表格做单独的处理，找到有随机变量和输入变量的地方:
 *			1、如何判断变量为随机变量和输入变量：判断随机变量（变量的表达式里面包含Random）,判断输入变量（）
 *			2、获得这些变量所影响到的物体,是否需要记录该物体的所有子物体；
 *			3、每个变量可能会影响到其他的变量（公式）；
 *	3、一旦存储结构不为空，在每行表格都要检测下，当前行是否会被存储结构中的随机变量和输入变量影响到，如果被影响到：记录当前表格和行数，并扩展该变量的影响（物体）信息。
 *	4、检测是否影响到：1、需要检测这行运动里面的Group；2、这行里面的相对物体；3、这行用到了随机变量或者随机变量影响到的公式。
 *	
 *	实现：
 *	1、在每行运行结束后，检测一个临时存储结构，这个结构存储上行用到的随机变量和输入变量。如果这个结构不为空,开始记录；
 *	
 * 
 *	可能出现的问题：
 *  1、一个随机变量和输入变量是否可以出现多次？如果出现多次……如何处理
 *  2、
 *
 */
public class CheckVar : MonoBehaviour {

	//将要存储运动涉及到的随机变量和输入变量
	public static List<SpecialVar> _SpecialVars = new List<SpecialVar>();

	//现有存储运动涉及到的随机变量和输入变量
	public static List<SpecialVar> _RecordSpecialVars = new List<SpecialVar>();
	public static Dictionary<string, SpecialVar> _DicRecordSpecialVars = new Dictionary<string, SpecialVar>();

	//运行时改变的随机变量和输入变量
	public static Dictionary<string, object> _ChangedVars = new Dictionary<string, object>();

	//运行时改变的随机变量和输入变量
	public static Dictionary<string, Dictionary<string, object>> _AllChangedVars = new Dictionary<string, Dictionary<string, object>>();

	//初始化
	public static void Initial(string filePath) {

		if (!File.Exists(filePath))
		{
			return;
		}

		ExcelOperator eo = new ExcelOperator();
		DataTable dt = eo.ExcelReader(filePath, "Variables");

		if (dt == null || dt.Rows.Count == 0)
		{
			Debug.LogWarning(filePath + "文件不存在工作表Variables或Variables里面为空！");
			return;
		}

		_RecordSpecialVars.Clear();
		_DicRecordSpecialVars.Clear();
		for (int i = 0; i < dt.Rows.Count; i++ )
		{
			DataRow dr = dt.Rows[i];
			SpecialVar tmpSpecialVar = new SpecialVar();

			//变量名
			tmpSpecialVar.VarID = dr[0].ToString();

			//出现表格
			tmpSpecialVar.ExcelName = dr[1].ToString();

			//出现行
			tmpSpecialVar.ExcelRow = int.Parse(dr[2].ToString());

			//出现内容
			tmpSpecialVar.ExcelContent = dr[3].ToString();

			//影响到的物体
			string[] tmpStrs = dr[4].ToString().Split(',');
			for (int j = 0; j < tmpStrs.Length; j++ )
			{
				if (tmpStrs[j] != "")
				{
					tmpSpecialVar.relatedObj.Add(tmpStrs[j]);
				}
			}

			//影响到的公式
			tmpStrs = dr[5].ToString().Split(',');
			for (int j = 0; j < tmpStrs.Length; j++)
			{
				if (tmpStrs[j] != "")
				{
					tmpSpecialVar.relatedExps.Add(tmpStrs[j]);
				}
			}

			//影响到的表格
			tmpStrs = dr[6].ToString().Split(',');
			for (int j = 0; j < tmpStrs.Length; j++)
			{
				if (tmpStrs[j] != "")
				{
					tmpSpecialVar.relatedExcel.Add(tmpStrs[j]);
				}
			}

			//加入存储结构
			_RecordSpecialVars.Add(tmpSpecialVar);
			_DicRecordSpecialVars.Add(tmpSpecialVar.VarID + "_" + tmpSpecialVar.ExcelName + "_" + tmpSpecialVar.ExcelRow, tmpSpecialVar);
		}
	}

	public static SpecialVar getSpecialVar(string tmpStr){
		SpecialVar tmpSpecialVar = new SpecialVar();

		string[] tmpStrsss = tmpStr.Split('_');
		string varName = tmpStrsss[0];
		int targetTable = int.Parse(tmpStrsss[1].Substring(1));
		int targetRow = int.Parse(tmpStrsss[2]);

		List<string> tmpList = new List<string>(_DicRecordSpecialVars.Keys);
		for (int i = 0; i < tmpList.Count; i++ )
		{
			string[] tmpStrsss2 = tmpList[i].Split('_');
			string varName2 = tmpStrsss2[0];
			int targetTable2 = int.Parse(tmpStrsss2[1].Substring(1));
			int targetRow2 = int.Parse(tmpStrsss2[2]);

			if (varName2 == varName)
			{
				if (targetTable > targetTable2 || (targetTable == targetTable2 && targetRow > targetRow2))
				{
					tmpSpecialVar = _DicRecordSpecialVars[tmpList[i]];
				}
				else{
					break;
				}
			}
		}

		return tmpSpecialVar;
	}

	//输出变量
	public static void OutputCheckVar(string fileName) {

		ExcelOperator eo = new ExcelOperator();
		string tmpFileName = fileName;
		string tmpSheetName = "Variables";
		List<string> columnName = new List<string>();
		columnName.Add("变量名"); columnName.Add("出现表格"); columnName.Add("出现行"); columnName.Add("出现内容"); 
		columnName.Add("影响到的物体");columnName.Add("影响到的公式"); columnName.Add("影响到的表格行");
		List<List<string>> outputInfo = new List<List<string>>();

		for (int i = 0; i < _SpecialVars.Count; i++ )
		{
			//Debug.Log("CheckVar OutputCheckVar :" + i + "," + _SpecialVars[i].VarID + "," + _SpecialVars[i].ExcelName + "," +						_SpecialVars[i].ExcelRow );
			List<string> singleStep = new List<string>();
			singleStep.Add(_SpecialVars[i].VarID);
			singleStep.Add(_SpecialVars[i].ExcelName);
			singleStep.Add(_SpecialVars[i].ExcelRow.ToString());
			singleStep.Add(_SpecialVars[i].ExcelContent);

			//影响物体
			string tmpObjsStr = "";
			for (int j = 0; j < _SpecialVars[i].relatedObj.Count; j++ )
			{
				//Debug.Log("relatedObj :" + j + "," + _SpecialVars[i].relatedObj[j]);
				
				if(j == 0){
					tmpObjsStr = _SpecialVars[i].relatedObj[j];
				}
				else{
					tmpObjsStr += ("," + _SpecialVars[i].relatedObj[j]);
				}
			}
			singleStep.Add(tmpObjsStr);

			//影响公式
			tmpObjsStr = "";
			for (int j = 0; j < _SpecialVars[i].relatedExps.Count; j++)
			{
				//Debug.Log("relatedExps :" + j + "," + _SpecialVars[i].relatedExps[j]);

				if (j == 0)
				{
					tmpObjsStr = _SpecialVars[i].relatedExps[j];
				}
				else
				{
					tmpObjsStr += ("," + _SpecialVars[i].relatedExps[j]);
				}
			}
			singleStep.Add(tmpObjsStr);

			//影响表格
			tmpObjsStr = "";
			for (int j = 0; j < _SpecialVars[i].relatedExcel.Count; j++)
			{
				//Debug.Log("relatedExps :" + j + "," + _SpecialVars[i].relatedExcel[j]);

				if (j == 0)
				{
					tmpObjsStr = _SpecialVars[i].relatedExcel[j];
				}
				else
				{
					tmpObjsStr += ("," + _SpecialVars[i].relatedExcel[j]);
				}
			}
			singleStep.Add(tmpObjsStr);

			outputInfo.Add(singleStep);
		}

		eo.ExcelWriter(tmpFileName, tmpSheetName, columnName, outputInfo, true);
	}
}

public class SpecialVar {
	//变量ID
	public string VarID;

	//变量出现的表格
	public string ExcelName;
	//变量出现在表格的行数
	public int ExcelRow;
	//表格内容
	public string ExcelContent;

	//这个变量影响到的物体
	public List<string> relatedObj = new List<string>();

	//这个变量影响到的公式
	public List<string> relatedExps = new List<string>();

	//该变量影响到的excel,excel中的行数
	//public Dictionary<string, List<int>> relatedExcel = new Dictionary<string, List<int>>();

	//该变量影响到的excel,excel中的行数
	public List<string> relatedExcel = new List<string>();
}
